home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 17 / CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso / CUCD / Programming / DiceSource / src / dutil / fdtopragma.c < prev    next >
C/C++ Source or Header  |  1997-09-09  |  9KB  |  444 lines

  1. /*
  2.  *    (c)Copyright 1992-1997 Obvious Implementations Corp.  Redistribution and
  3.  *    use is allowed under the terms of the DICE-LICENSE FILE,
  4.  *    DICE-LICENSE.TXT.
  5.  */
  6.  
  7. /*
  8.  *  FDTOPRAGMA.C
  9.  *
  10.  *  FDTOPRAGMA fdfile [-o inline_header_file]
  11.  *  FDTOPRAGMA fddir  [-o inlinedir]
  12.  *
  13.  *  Generates an #include file for inline library calls given an FD file
  14.  *  and CLIB-style prototype file.  The generated header file consists of
  15.  *  entries as follows:
  16.  *
  17.  *  void func1(__A6 void *,__D0 int, __D1 int);
  18.  *  #pragma FubarBase func1 2e 0102
  19.  *  ...
  20.  */
  21.  
  22. #ifdef AMIGA
  23. #include <exec/types.h>
  24. #include <exec/nodes.h>
  25. #include <exec/lists.h>
  26. #include <clib/alib_protos.h>
  27. #include <clib/exec_protos.h>
  28. #include <clib/dos_protos.h>
  29. #include <clib/alib_protos.h>
  30. #include <lib/profile.h>
  31. #include <lib/version.h>
  32. #include <lists.h>
  33. #else
  34. #include <suplib/all.h>
  35. #include <include/lib/profile.h>
  36. #include <include/lib/version.h>
  37. #endif
  38. #include <stdio.h>
  39. #include <stdlib.h>
  40. #include <string.h>
  41. #include <stdarg.h>
  42. #include <fcntl.h>
  43. #include <sys/stat.h>
  44. #include <sys/file.h>
  45. #include <sys/dir.h>
  46. #include <time.h>
  47.  
  48. IDENT("FDTOPRAGMA", ".9");
  49. DCOPYRIGHT;
  50.  
  51. typedef unsigned char  ubyte;
  52. typedef unsigned short uword;
  53. #ifndef linux
  54. typedef unsigned long  ulong;
  55. #endif
  56. typedef struct List    List;
  57. typedef struct Node    Node;
  58.  
  59. typedef struct FDNode {
  60.     Node    fn_Node;
  61.     short   fn_Args;
  62.     long    fn_Offset;        /*    library offset        */
  63.     char    fn_Regs[32];    /*    transfer registers  */
  64. } FDNode;
  65.  
  66. void    help(short);
  67. void    exiterr(const char *, ...);
  68. void    ScanFD(FILE *);
  69. char    *ParseArg(char *, char **);
  70. void    GenerateOutput(FILE *, char *);
  71. void    GenerateFunction(char *, long);
  72. void    GeneratePragmas(char *, char *);
  73.  
  74. List    FDList;     /*  list of FD files   */
  75.  
  76. char    *BaseVar;
  77. char    *BaseVarPtr;
  78.  
  79. char    Buf[256];
  80.  
  81. int _DiceCacheEnable = 1;
  82.  
  83. int
  84. main(int ac, char **av)
  85. {
  86.     short i;
  87.     struct stat s;
  88.     char *fdName = NULL;
  89.     char *outName = NULL;
  90.  
  91.     for (i = 1; i < ac; ++i) {
  92.     char *ptr = av[i];
  93.  
  94.     if (*ptr != '-') {
  95.         if (fdName == NULL)fdName = ptr;
  96.         else help(1);
  97.         continue;
  98.     }
  99.     ptr += 2;
  100.     switch(ptr[-1]) {
  101.     case 'o':
  102.         outName = (*ptr) ? ptr : av[++i];
  103.         break;
  104.     default:
  105.         help(0);
  106.         break;
  107.     }
  108.     }
  109.     if (fdName == NULL)
  110.     help(0);
  111.  
  112.     /*
  113.      *    HACK, handle case where fdName is a directory
  114.      */
  115.     if (stat(fdName, &s) == 0 && (s.st_mode & S_IFDIR)) {
  116.     DIR *dir;
  117.     struct direct *direct;
  118.  
  119.     if ((dir = opendir(fdName)) != NULL) {
  120.         while ((direct = readdir(dir)) != NULL) {
  121.         char *ptr;
  122.  
  123.         if ((ptr = strstr(direct->d_name, "_lib.fd")) != NULL) {
  124.             static char FdPath[256];
  125.             static char OutPath[256];
  126.  
  127.             sprintf(FdPath, "%s%s", fdName, direct->d_name);
  128.             sprintf(OutPath, "%s%.*s_pragmas.h", outName ? outName : "",
  129.                              ptr - direct->d_name, direct->d_name);
  130.             GeneratePragmas(FdPath, OutPath);
  131.         } else {
  132.             fprintf(stderr, "%s: expected '_lib.fd' trailer\n", direct->d_name);
  133.         }
  134.         }
  135.         closedir(dir);
  136.     }
  137.     }
  138.     else {
  139.     GeneratePragmas(fdName, outName);
  140.     }
  141.     return(0);
  142. }
  143.  
  144. void
  145. GeneratePragmas(fdFile, outFile)
  146. char *fdFile;
  147. char *outFile;
  148. {
  149.     NewList(&FDList);
  150.     BaseVarPtr = BaseVar = NULL;
  151.  
  152.     if(outFile)printf("FD=%s OUT=%s\n", fdFile, outFile);
  153.     else printf("FD=%s\n", fdFile);
  154.  
  155.     /*
  156.      *    Generate FD specifications from FD file
  157.      */
  158.  
  159.     {
  160.     FILE *fi;
  161.     if ((fi = fopen(fdFile, "r")) == NULL)
  162.         exiterr("Unable to open .FD file: %s", fdFile);
  163.     ScanFD(fi);
  164.     fclose(fi);
  165.     }
  166.  
  167.     /*
  168.      *    Generate output
  169.      */
  170.  
  171.     if (outFile) {
  172.     FILE *fo;
  173.  
  174.     if ((fo = fopen(outFile, "w")) != NULL) {
  175.         GenerateOutput(fo, outFile);
  176.         fclose(fo);
  177.     } else {
  178.         exiterr("Can't create %s\n", outFile);
  179.     }
  180.     } else {
  181.     GenerateOutput(stdout, outFile);
  182.     }
  183. }
  184.  
  185. void
  186. exiterr(const char *ctl, ...)
  187. {
  188.     va_list va;
  189.  
  190.     va_start(va, ctl);
  191.     vfprintf(stderr, ctl, va);
  192.     va_end(va);
  193.     fprintf(stderr, "\n");
  194.     exit(5);
  195. }
  196.  
  197. void
  198. help(short code)
  199. {
  200.     puts(Ident);
  201.     puts(DCopyright);
  202.     puts("FDTOPRAGMA fdfile [-o outfile]");
  203.     puts("FDTOPRAGMA fddir/ [-o outdir/]");
  204.     puts("  Generates header files for inline library calls");
  205.     exit(code);
  206. }
  207.  
  208. void
  209. ScanFD(fi)
  210. FILE *fi;
  211. {
  212.     long bias = -1;
  213.     short end = 0;
  214.     short public = 1;
  215.  
  216.     char *key;
  217.  
  218.     while (fgets(Buf, sizeof(Buf), fi)) {
  219.     if (Buf[0] == '\n' || Buf[0] == '*')
  220.         continue;
  221.     if (strncmp(Buf, "##", 2) != 0) {
  222.         if (bias < 0 || BaseVar == NULL) {
  223.         if (bias < 0) {
  224.             bias = 30;
  225.             printf("Error, No ##bias before function: %s\n", Buf);
  226.         }
  227.         if (BaseVar == NULL) {
  228.             BaseVarPtr = BaseVar = strdup("UnknownBase");
  229.             printf("Error, No ##base before function: %s\n", Buf);
  230.         }
  231.         }
  232.         if (public)
  233.         GenerateFunction(Buf, bias);
  234.         bias += 6;
  235.         continue;
  236.     }
  237.     if ((key = strtok(Buf + 2, " \t\n")) == NULL) {
  238.         printf("\tError, Illegal null directive\n");
  239.         continue;
  240.     }
  241.     if (stricmp(key, "base") == 0) {
  242.         if ((key = strtok(NULL, " \t\n")) != NULL) {
  243.         if (BaseVar)
  244.             free(BaseVar);
  245.         BaseVarPtr = BaseVar = strdup(key);
  246.         if (BaseVar[0] == '_')
  247.             ++BaseVarPtr;
  248.         } else {
  249.         printf("\tError, Illegal ##base directive\n");
  250.         }
  251.         continue;
  252.     }
  253.     if (stricmp(key, "bias") == 0) {
  254.         if ((key = strtok(NULL, " \t\n")) != NULL) {
  255.         char *dummy;
  256.  
  257.         bias = strtol(key, &dummy, 0);
  258.         if (bias <= 0)
  259.             printf("\tError, Illegal ##bias: %ld\n", bias);
  260.         } else {
  261.         printf("\tError, Illegal ##bias directive\n");
  262.         }
  263.         continue;
  264.     }
  265.     if (stricmp(key, "public") == 0) {
  266.         public = 1;
  267.         continue;
  268.     }
  269.     if (stricmp(key, "private") == 0) {
  270.         public = 0;
  271.         continue;
  272.     }
  273.     if (stricmp(key, "end") == 0) {
  274.         end = 1;
  275.         break;
  276.     }
  277.     printf("\tError, Unrecognized directive: %s\n", key);
  278.     }
  279.     if (bias < 0)
  280.     puts("\tUnexpected EOF, no ##bias");
  281.     if (BaseVar == NULL)
  282.     puts("\tUnexpected EOF, no ##base");
  283.     if (end == 0)
  284.     puts("\tUnexpected EOF, no ##end directive");
  285. }
  286.  
  287. /*
  288.  *  funcname(var,var,var)(reg,reg,reg)        (or reg/reg)
  289.  */
  290.  
  291. void
  292. GenerateFunction(buf, bias)
  293. char *buf;
  294. long bias;
  295. {
  296.     FDNode *fd = malloc(sizeof(FDNode));
  297.     char *scanPtr = buf;
  298.  
  299.     clrmem(fd, sizeof(FDNode));
  300.  
  301.     fd->fn_Offset = bias;
  302.  
  303.     {
  304.     short noArgs = 0;
  305.  
  306.     while (*scanPtr && *scanPtr != '\t' && *scanPtr != ' ' && *scanPtr != '(')
  307.         ++scanPtr;
  308.     if (*scanPtr == ' ' || *scanPtr == '\t') {
  309.         while (*scanPtr && *scanPtr != '(')
  310.         *scanPtr++ = 0;
  311.     }
  312.     if (*scanPtr == '(') {
  313.         *scanPtr++ = 0;
  314.         if (*scanPtr == ')')
  315.         noArgs = 1;
  316.     }
  317.     while (*scanPtr && *scanPtr != ')')   /*  skip text args  */
  318.         ++scanPtr;
  319.     while (*scanPtr && *scanPtr != '(')
  320.         ++scanPtr;
  321.     if (noArgs == 0 && *scanPtr == 0) {
  322.         printf("\tError in line: %s\n", buf);
  323.         return;
  324.     }
  325.     }
  326.     fd->fn_Node.ln_Name = strdup(buf);
  327.  
  328.     /*
  329.      *    get register description
  330.      */
  331.  
  332.     if (*scanPtr)
  333.     ++scanPtr;
  334.  
  335.     for (fd->fn_Args = 0; *scanPtr && *scanPtr != '\n' && *scanPtr != ')'; ++fd->fn_Args) {
  336.     switch(*scanPtr) {
  337.     case 'd':
  338.     case 'D':
  339.         fd->fn_Regs[fd->fn_Args] = *++scanPtr - '0';
  340.         ++scanPtr;
  341.         break;
  342.     case 'a':
  343.     case 'A':
  344.         fd->fn_Regs[fd->fn_Args] = *++scanPtr - '0' + 8;
  345.         ++scanPtr;
  346.         break;
  347.     default:
  348.         printf("\tError in register spec: %s\n", scanPtr);
  349.         return;
  350.     }
  351.     if (*scanPtr == ',' || *scanPtr == '/')
  352.         ++scanPtr;
  353.     }
  354.     if (fd->fn_Args == 0 && *scanPtr != ')') {
  355.     printf("\tError in register spec: %s\n", scanPtr);
  356.     return;
  357.     }
  358.     AddTail(&FDList, &fd->fn_Node);
  359. }
  360.  
  361.  
  362. char *
  363. ParseArg(ptr, ppt)
  364. char *ptr;
  365. char **ppt;
  366. {
  367.     char *base = ptr;
  368.  
  369.     if (ptr) {
  370.     while (*ptr && *ptr != '(')
  371.         ++ptr;
  372.     if (*ptr == '(') {
  373.         for (base = ++ptr; *ptr && *ptr != ')'; ++ptr)
  374.         ;
  375.         if (*ptr == ')') {
  376.         *ptr++ = 0;
  377.         *ppt = strdup(base);
  378.         } else {
  379.         ptr = NULL;
  380.         }
  381.     } else {
  382.         ptr = NULL;
  383.     }
  384.     }
  385.     return(ptr);
  386. }
  387.  
  388. void
  389. GenerateOutput(fo, outFile)
  390. FILE *fo;
  391. char *outFile;
  392. {
  393.     FDNode *fd;
  394.  
  395.     /* ** $ VER: proto/diskfont.h 1.0 (17.4.93) **        */
  396.     /* #ifndef DISKFONT_PROTO_H                          */
  397.     /* #define DISKFONT_PROTO_H 1                        */
  398.     /* #include <pragmas/config.h>                       */
  399.     /* #include <exec/types.h>                           */
  400.     /* #include <clib/diskfont_protos.h>                 */
  401.     /* #ifdef __SUPPORTS_PRAGMAS__                       */
  402.     /* extern struct Library *DiskfontBase;              */
  403.     /* #include <pragmas/diskfont_pragmas.h>             */
  404.     /* #endif                                            */
  405.     /* #endif                                            */
  406.  
  407.     {
  408.     time_t t;
  409.     struct tm *tp;
  410.  
  411.     time(&t);
  412.     tp = localtime(&t);
  413.  
  414.     fprintf(fo, "/* %cVER: %s 1.0 (%d.%d.%d) */\n",
  415.                '$',
  416.                outFile ? outFile : "",
  417.                (int)tp->tm_mday, 
  418.                (int)tp->tm_mon, 
  419.                (int)tp->tm_year
  420.         );
  421.     }
  422.  
  423.     fprintf(fo, "#ifndef %s_PRAGMA_H\n", BaseVarPtr);
  424.     fprintf(fo, "#define %s_PRAGMA_H\n\n", BaseVarPtr);
  425.  
  426.     /*
  427.      *    #define's to generate library calls
  428.      */
  429.  
  430.     for (fd = GetHead(&FDList); fd; fd = GetSucc(&fd->fn_Node))
  431.     {
  432.     short i;
  433.  
  434.     fprintf(fo, "#pragma libcall %s %s %lx ", BaseVarPtr,
  435.                 fd->fn_Node.ln_Name, fd->fn_Offset);
  436.  
  437.     for (i = fd->fn_Args - 1; i >= 0; --i)
  438.         fprintf(fo, "%x", fd->fn_Regs[i]);
  439.     fprintf(fo, "0%x\n", fd->fn_Args & 15);
  440.     }
  441.     fprintf(fo, "\n#endif\n");
  442. }
  443.  
  444.